package com.veer.shop.aop;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.veer.shop.annotation.ApiControllerLog;
import com.veer.shop.mapper.ApiLogMapper;
import com.veer.shop.pojo.ApiLog;
import com.veer.shop.utils.DateTimeUtil;
import com.veer.shop.utils.IPUtil;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Api 日志接口 Aop 切面
 * 
 * @author WangBin
 * 2020年9月21日-上午9:40:11
 */
@Aspect
@Component
public class AopApiLogAspect {
	
	private static Logger logger = LoggerFactory.getLogger(AopApiLogAspect.class);
	
	@Autowired
	ApiLogMapper apiLogMapper;
	@Autowired
	ObjectMapper jackJsonMapper;

	@Pointcut("execution(public * com.veer.shop.controller..*.*(..)) && !execution(public * com.veer.shop.controller.admin.ImportController.*(..))")
	public void apiLog() {}
	
	@Around("apiLog()")
	public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
		logger.info("进入 Aop 切面 Around 方法, 记录接口日志！");
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		
		ApiLog apiLogEntity = new ApiLog();
		
		// api 地址
		apiLogEntity.setApiPath(request.getRequestURI());
		// 请求参数
		apiLogEntity.setParams(jackJsonMapper.writeValueAsString(joinPoint.getArgs()));
		// 客户端IP
		apiLogEntity.setRemoteIp(IPUtil.getIpAddress(request));
		// 接口描述
		String apiTitle = "";
		ApiControllerLog annotation = null;
		MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        Method method = sign.getMethod();
        annotation = method.getAnnotation(ApiControllerLog.class);
        if(annotation != null) {
        	apiTitle = annotation.description();
        }
		apiLogEntity.setApiTitle(apiTitle);
		// 请求开始时间戳
		apiLogEntity.setStartTime(System.currentTimeMillis());
		// 接口返回数据
		Object result = joinPoint.proceed();
		apiLogEntity.setResponse(jackJsonMapper.writeValueAsString(result));
		// 接口执行结束时间戳
		apiLogEntity.setEndTime(System.currentTimeMillis());
		// 接口执行耗时
		apiLogEntity.setRunTime(apiLogEntity.getEndTime() - apiLogEntity.getStartTime());
		// 接口调用时间
		apiLogEntity.setCreatedAt(DateTimeUtil.getDateTime());
		
        apiLogMapper.insert(apiLogEntity);
        
        return result;
	}
}
